// #include <iostream>

// using namespace std;

// #include <cstring>
// #include <cstdlib>

// #include <unistd.h>
// #include <fcntl.h>

// bool SetNonBlock(int fd)
// {
//     int fl = fcntl(fd, F_GETFL);
//     if (fl < 0)
//     {
//         cerr << "fcntl error" << endl;
//         return false;
//     }
//     fcntl(fd, F_SETFL, fl | O_NONBLOCK);
//     return true;
// }

// int main()
// {
//     char buffer[1024];
//     SetNonBlock(0);
//     while (true)
//     {
//         ssize_t size = read(0, buffer, sizeof(buffer) - 1);
//         if (size > 0)
//         {
//             buffer[size - 1] = 0;
//             cout << "echo >>>" << buffer << endl;
//         }
//         else
//         {
//             if (errno == EAGAIN || errno == EWOULDBLOCK) //底层没有数据可以读取
//             {
//                 cout << "strerr: " << strerror(errno) << " code: " << errno << endl;
//                 sleep(1);
//                 continue;
//             }
//             else if (errno == EINTR) // 在读取数据之前被信号中断
//             {
//                 std::cout << strerror(errno) << std::endl;
//                 sleep(1);
//                 continue;
//             }
//             else
//             {
//                 cout << "read error" << endl;
//                 break;
//             }
//         }
//     }
//     return 0;
// }

#include <iostream>
#include <string>
#include <vector>
#include <functional>
using namespace std;

#include <cstring>
#include <cstdlib>

#include <unistd.h>
#include <fcntl.h>

void PrintLog()
{
    cout << "这是一个打印日志任务..." << endl;
}
void OperMysql()
{
    cout << "这是一个数据库语句任务..." << endl;
}
void CheckNet()
{
    cout << "这是一个检查网路情况任务..." << endl;
}

using func_t = function<void(void)>;
vector<func_t> tasks;

void LoadTask()
{
    tasks.push_back(PrintLog);
    tasks.push_back(OperMysql);
    tasks.push_back(CheckNet);
}

void HandlerTask()
{
    for (auto &task : tasks)
    {
        task();
    }
}

bool SetNonBlock(int fd)
{
    int fl = fcntl(fd, F_GETFL);
    if (fl < 0)
    {
        cerr << "error:" << strerror(errno) << endl;
        return false;
    }
    int ret = fcntl(fd, F_SETFL, fl | O_NONBLOCK);
    if (ret < 0)
    {
        cerr << "error:" << strerror(errno) << endl;
        return false;
    }
    return true;
}

int main()
{
    SetNonBlock(0);
    char buffer[1024];
    LoadTask();
    while (true)
    {
        cout << ">>>";
        int n = read(0, buffer, sizeof(buffer) - 1); // 检验条件是否就绪（等）+拷贝
        if (n > 0)                                   // 标准输入的数据就绪，可以进行读取
        {
            buffer[n] = 0;
            cout << "echo#" << buffer << endl;
        }
        else // 读取数据出现报错
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK) // 因为没有数据而报错，执行其它任务后，在进行读取试探
            {
                HandlerTask();
                sleep(1);
                continue;
            }
            else if (errno == EINTR) // 读取数据时因为信号到来而终止
            {
                continue;
            }
            else // 真正的出错了
            {
                cerr << "error:" << strerror(errno) << endl;
                break;
            }
        }
    }
    return 0;
}
